﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YJKRevitKernel.CurveUtility.ColinearCurveGroup;
using YJKRevitKernel.RevitTopologySuite;
using Teigha.TD;

namespace YJKCopyModel.LastFastModeling
{
	public class PointPosBlockWindMouthInfo : PointPosBlockInfo
	{
		public double BlockWidth
		{
			get
			{
				return this.m_BlockWidth;
			}
		}

		public double BlockHeight
		{
			get
			{
				return this.m_BlockHeight;
			}
		}

		public XYZ BlockPlaceLocation
		{
			get
			{
				return this.m_BlockPlaceLocation;
			}
			set
			{
				this.m_BlockPlaceLocation = value;
			}
		}

		public PointPosBlockWindMouthInfo(OdDbBlockReference odDbBlockRef, ImportInstance ImportIns) : base(odDbBlockRef, ImportIns)
		{
			base.GetCurves();
		}

		public bool GetBlockWidthAndHeight(List<CurveOutBoxType> getOutBoxOrders)
		{
			bool flag = base.LstCurves == null || getOutBoxOrders == null || getOutBoxOrders.Count <= 0;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				List<Curve> lineCurves = null;
				List<Curve> arcCurves = null;
				BussinessCommon.SeparateCurves(base.LstCurves, out lineCurves, out arcCurves);
				List<Curve> list = null;
				CurveOutBoxType curType = CurveOutBoxType.None;
				foreach (CurveOutBoxType curveOutBoxType in getOutBoxOrders)
				{
					bool outBoxCurvesByType = this.GetOutBoxCurvesByType(lineCurves, arcCurves, curveOutBoxType, out list);
					if (outBoxCurvesByType)
					{
						curType = curveOutBoxType;
						break;
					}
				}
				double blockWidth = 0.0;
				double blockHeight = 0.0;
				XYZ blockPlaceLocation = null;
				bool flag2 = false;
				bool flag3 = list != null && list.Count > 0;
				if (flag3)
				{
					flag2 = this.GetBlockWidthAndHeightByType(list, curType, out blockWidth, out blockHeight, out blockPlaceLocation);
				}
				bool flag4 = !flag2;
				if (flag4)
				{
					flag2 = this.GetBlockWidthAndHeight(out blockWidth, out blockHeight, out blockPlaceLocation);
				}
				this.m_BlockWidth = blockWidth;
				this.m_BlockHeight = blockHeight;
				this.m_BlockPlaceLocation = blockPlaceLocation;
				result = flag2;
			}
			return result;
		}

		private bool GetBlockWidthAndHeightByType(List<Curve> maxBoxCurves, CurveOutBoxType curType, out double width, out double height, out XYZ center)
		{
			width = 0.0;
			height = 0.0;
			center = null;
			bool flag = maxBoxCurves == null || maxBoxCurves.Count <= 0;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				double num = 0.0;
				double num2 = 0.0;
				bool flag2 = curType == CurveOutBoxType.CloseRectangle || curType == CurveOutBoxType.NoCloseRectangle;
				if (flag2)
				{
					bool flag3 = !PointPosBlockWindMouthInfo.GetCurveLength(maxBoxCurves[0], out num) || !PointPosBlockWindMouthInfo.GetCurveLength(maxBoxCurves[1], out num2);
					if (flag3)
					{
						return false;
					}
					center = this.GetRectangleCenter(maxBoxCurves);
					bool flag4 = center == null;
					if (flag4)
					{
						return false;
					}
				}
				else
				{
					bool flag5 = curType == CurveOutBoxType.CloseCircle;
					if (!flag5)
					{
						return false;
					}
					bool flag6 = !PointPosBlockWindMouthInfo.GetArcCurveLength(maxBoxCurves[0], out num, out num2);
					if (flag6)
					{
						return false;
					}
					bool flag7 = !PointPosBlockWindMouthInfo.GetArcCurveCenter(maxBoxCurves[0], out center);
					if (flag7)
					{
						return false;
					}
				}
				center = this.RemoveZValue(center);
				bool flag8 = num > num2;
				if (flag8)
				{
					width = num;
					height = num2;
				}
				else
				{
					width = num2;
					height = num;
				}
				result = true;
			}
			return result;
		}

		private bool GetBlockWidthAndHeight(out double width, out double height, out XYZ center)
		{
			width = 0.0;
			height = 0.0;
			center = null;
			bool flag = base.ActualBox == null || base.ActualBox.Count != 4;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				center = (base.ActualBox[0] + base.ActualBox[2]) / 2.0;
				center = this.RemoveZValue(center);
				XYZ xyz = new XYZ(base.ActualBox[0].X, base.ActualBox[0].Y, 0.0);
				XYZ xyz2 = new XYZ(base.ActualBox[1].X, base.ActualBox[1].Y, 0.0);
				XYZ xyz3 = new XYZ(base.ActualBox[3].X, base.ActualBox[3].Y, 0.0);
				double num = xyz.DistanceTo(xyz3);
				double num2 = xyz.DistanceTo(xyz2);
				bool flag2 = num > num2;
				if (flag2)
				{
					width = num;
					height = num2;
				}
				else
				{
					width = num2;
					height = num;
				}
				result = true;
			}
			return result;
		}

		public static bool GetCurveLength(Curve c, out double length)
		{
			length = 0.0;
			bool flag = c == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				length = c.GetEndPoint(0).DistanceTo(c.GetEndPoint(1));
				result = true;
			}
			return result;
		}

		public static bool GetArcCurveLength(Curve c, out double length, out double height)
		{
			length = 0.0;
			height = 0.0;
			bool flag = c == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				bool flag2 = c is Arc;
				if (flag2)
				{
					Arc arc = c as Arc;
					length = 2.0 * arc.Radius;
					height = length;
					result = true;
				}
				else
				{
					bool flag3 = c is Ellipse;
					if (flag3)
					{
						Ellipse ellipse = c as Ellipse;
						length = 2.0 * ellipse.RadiusX;
						height = 2.0 * ellipse.RadiusY;
						result = true;
					}
					else
					{
						result = false;
					}
				}
			}
			return result;
		}

		public static bool GetArcCurveCenter(Curve c, out XYZ center)
		{
			center = null;
			bool flag = c == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				bool flag2 = c is Arc;
				if (flag2)
				{
					Arc arc = c as Arc;
					center = arc.Center;
					result = true;
				}
				else
				{
					bool flag3 = c is Ellipse;
					if (flag3)
					{
						Ellipse ellipse = c as Ellipse;
						center = ellipse.Center;
						result = true;
					}
					else
					{
						result = false;
					}
				}
			}
			return result;
		}

		private bool GetOutBoxCurvesByType(List<Curve> lineCurves, List<Curve> arcCurves, CurveOutBoxType curveOutBoxType, out List<Curve> maxBoxCurves)
		{
			maxBoxCurves = new List<Curve>();
			bool result = false;
			switch (curveOutBoxType)
			{
			case CurveOutBoxType.CloseRectangle:
				result = this.GetMaxRectangle(lineCurves, false, out maxBoxCurves);
				break;
			case CurveOutBoxType.NoCloseRectangle:
				result = this.GetMaxRectangle(lineCurves, true, out maxBoxCurves);
				break;
			case CurveOutBoxType.CloseCircle:
				result = this.GetMaxArc(arcCurves, out maxBoxCurves);
				break;
			}
			return result;
		}

		private bool GetMaxArc(List<Curve> arcCurves, out List<Curve> maxAreaBox)
		{
			maxAreaBox = new List<Curve>();
			bool flag = arcCurves == null || arcCurves.Count <= 0;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				List<Arc> list = new List<Arc>();
				foreach (Curve curve in arcCurves)
				{
					bool flag2 = curve == null;
					if (!flag2)
					{
						Arc arc = curve as Arc;
						bool flag3 = arc != null && !arc.IsBound && arc.IsCyclic;
						if (flag3)
						{
							list.Add(arc);
						}
					}
				}
				List<Arc> list2 = (from a in list
				orderby a.Radius descending
				select a).ToList<Arc>();
				foreach (Arc item in list2)
				{
					List<Curve> list3 = new List<Curve>();
					list3.Add(item);
					bool flag4 = this.CheckIsCircle(list3);
					if (flag4)
					{
						maxAreaBox = list3;
						return true;
					}
				}
				result = false;
			}
			return result;
		}

		private bool GetMaxRectangle(List<Curve> lineCurves, bool ifSplitInput, out List<Curve> maxAreaBox)
		{
			maxAreaBox = new List<Curve>();
			List<Curve> list = this.MergeCurves(lineCurves);
			bool flag = list == null || list.Count <= 0;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				RevitPolygonFinder revitPolygonFinder = new RevitPolygonFinder();
				List<RevitPolygonDataBean> list2 = null;
				List<RevitPolygonDataBean> source = null;
				bool flag2 = !revitPolygonFinder.TryGetPolygon(list, out list2, out source, ifSplitInput, 3, false);
				if (flag2)
				{
					result = false;
				}
				else
				{
					List<RevitPolygonDataBean> list3 = (from a in source
					where a != null && a.Area != null
					select a).ToList<RevitPolygonDataBean>();
					bool flag3 = list3 == null || list3.Count <= 0;
					if (flag3)
					{
						result = false;
					}
					else
					{
						List<RevitPolygonDataBean> list4 = (from a in list3
						orderby a.Area descending
						select a).ToList<RevitPolygonDataBean>();
						foreach (RevitPolygonDataBean revitPolygonDataBean in list4)
						{
							RevitPolygonDataBean revitPolygonDataBean2 = revitPolygonDataBean;
							List<Curve> list5 = new List<Curve>();
							foreach (Curve item in revitPolygonDataBean2.ShellCurveLoop)
							{
								list5.Add(item);
							}
							List<Curve> list6;
							if (ifSplitInput)
							{
								list6 = this.MergeCurves(list5);
							}
							else
							{
								list6 = list5;
							}
							bool flag4 = this.CheckIsRectangle(list6);
							if (flag4)
							{
								maxAreaBox = list6;
								return true;
							}
						}
						result = false;
					}
				}
			}
			return result;
		}

		private List<Curve> MergeCurves(List<Curve> lineCurves)
		{
			bool flag = lineCurves == null || lineCurves.Count <= 0;
			List<Curve> result;
			if (flag)
			{
				result = new List<Curve>();
			}
			else
			{
				ColinearGroupManager colinearGroupManager = new ColinearGroupManager(lineCurves);
				List<List<Curve>> colinearGroup = colinearGroupManager.GetColinearGroup();
				bool flag2 = colinearGroup == null || colinearGroup.Count <= 0;
				if (flag2)
				{
					result = lineCurves;
				}
				else
				{
					List<Curve> list = new List<Curve>();
					foreach (List<Curve> list2 in colinearGroup)
					{
						bool flag3 = list2 != null && list2.Count > 0;
						if (flag3)
						{
							list.AddRange(list2);
						}
					}
					result = list;
				}
			}
			return result;
		}

		private bool CheckIsCircle(List<Curve> curves)
		{
			bool flag = curves == null || curves.Count != 1;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				Curve curve = curves[0];
				bool flag2 = !curve.IsCyclic;
				result = !flag2;
			}
			return result;
		}

		private bool CheckIsRectangle(List<Curve> curves)
		{
			bool flag = curves == null || curves.Count != 4;
			return !flag;
		}

		private XYZ GetRectangleCenter(List<Curve> curves)
		{
			bool flag = curves == null || curves.Count != 4;
			XYZ result;
			if (flag)
			{
				result = null;
			}
			else
			{
				XYZ xyz = null;
				XYZ xyz2 = null;
				XYZ xyz3 = null;
				XYZ xyz4 = null;
				bool flag2 = !this.GetCurveCenter(curves[0], out xyz) || !this.GetCurveCenter(curves[1], out xyz2) || !this.GetCurveCenter(curves[2], out xyz3) || !this.GetCurveCenter(curves[3], out xyz4);
				if (flag2)
				{
					result = null;
				}
				else
				{
					result = ((xyz + xyz2) / 2.0 + (xyz3 + xyz4) / 2.0) / 2.0;
				}
			}
			return result;
		}

		private bool GetCurveCenter(Curve c, out XYZ center)
		{
			center = null;
			bool flag = c != null;
			bool result;
			if (flag)
			{
				center = (c.GetEndPoint(0) + c.GetEndPoint(1)) / 2.0;
				result = true;
			}
			else
			{
				result = false;
			}
			return result;
		}

		private XYZ RemoveZValue(XYZ point)
		{
			return new XYZ(point.X, point.Y, 0.0);
		}

		private double m_BlockWidth = 0.0;

		private double m_BlockHeight = 0.0;

		private XYZ m_BlockPlaceLocation;
	}
}
